package com.tom.architect02.ui20.day12;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;

import androidx.core.view.ViewCompat;

import com.tom.architect02.R;

/**
 * Added by Tom on 2024/06/11.
 */
public class SlidingMenu extends HorizontalScrollView {
    private Context mContext;
    private int mMenuWidth;
    private View mMenuView, mContentView;
    private GestureDetector mGestureDetector; // 快速滑动：系统自带的手势处理类
    private boolean mMenuIsOpen = false;  // 当前菜单是否打开
    private boolean mIsIntercept = false; // 是否拦截

    public SlidingMenu(Context context) {
        this(context, null);
    }
    public SlidingMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        // 初始化自定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
        float rightMargin = array.getDimension(
                R.styleable.SlidingMenu_menuRightMargin, dip2px(mContext, 50));
        // 菜单宽度= 屏幕宽度- 预留的宽度(自定义属性，默认50dp)
        mMenuWidth = (int) (getScreenWidth(mContext) - rightMargin);
        array.recycle();

        this.mGestureDetector = new GestureDetector(mContext, new GestureDetectorListener());
    }

    // GestureDetector.onGestureListener()
    private class GestureDetectorListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if(Math.abs(velocityY) > Math.abs(velocityX)){
                // 代表上下快速划  这个时候不做处理
                return super.onFling(e1, e2, velocityX, velocityX);
            }
//            Log.e("TAG", "velocityX -> " + velocityX);// 向右快速滑动会是正的  +   向左快速滑动 是  -
            // 只关注快速滑动：如果菜单是打开的   向右向左快速滑动都会回调这个方法
            if (mMenuIsOpen) {
                if (velocityX < 0) {
                    toggleMenu(); // 快速滑动触发了，下面的逻辑就不要处理。
                    return true;
                }
            } else {
                if (velocityX > 0) {
                    toggleMenu();
                    return true;
                }
            }
            return false;
        }
    }

    // 切换菜单
    private void toggleMenu() {
        if (mMenuIsOpen) {
            closeMenu();
        } else {
            openMenu();
        }
    }

    /**
     * 关闭菜单
     */
    private void closeMenu() {
        smoothScrollTo(mMenuWidth, 0); // 滚动到mMenuWidth的位置。
        mMenuIsOpen = false;
    }

    /**
     * 打开菜单
     */
    private void openMenu() {
        smoothScrollTo(0, 0); // 滚动到0的位置
        mMenuIsOpen = true;
    }

    // 布局解析完毕（xml解析完），调用。指定宽高
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // 内容的宽高= 屏幕宽度； 菜单的宽= 屏幕宽- 右边的距离。
        // LinearLayout
        ViewGroup container = (ViewGroup) getChildAt(0);
        int childCount = container.getChildCount();
        if (childCount != 2) {
            throw new RuntimeException("只能放置两个子View!");
        }

        mMenuView = container.getChildAt(0);
        // 设置只能通过 LayoutParams ，
        ViewGroup.LayoutParams menuParams = mMenuView.getLayoutParams();
        menuParams.width = mMenuWidth;
        // 7.0 以下的手机必须采用下面的方式
        mMenuView.setLayoutParams(menuParams);

        mContentView = container.getChildAt(1);
        ViewGroup.LayoutParams contentParams = mContentView.getLayoutParams();
        contentParams.width = getScreenWidth(getContext());
        mContentView.setLayoutParams(contentParams);
        // 2. 初始化进来是关闭 发现没用
        // scrollTo(mMenuWidth,0);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        scrollTo(mMenuWidth, 0);
    }

    // 4. 处理右边缩放，左边的缩放和透明度。需要时刻获取当前滚动的位置。
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // l的变化： mMenuWidth ~ 0 .
        float scale = 1f * l / mMenuWidth; // scale： 1~0
        // 右边的缩放：最小0.7f，最大是1f。
        float rightScale = 0.7f + 0.3f * scale;
        // 默认是以中心店缩放。要重新设置缩放中心点位置PivotX/PivotY.
        mContentView.setPivotX(0);
        mContentView.setPivotY(mContentView.getMeasuredHeight() / 2);
        mContentView.setScaleX(rightScale);
        mContentView.setScaleY(rightScale);

        // 菜单的缩放和透明度。
        // 透明度是 半透明到完全透明  0.5f - 1.0f
        float leftAlpha = 0.5f + (1-scale)*0.5f;
        ViewCompat.setAlpha(mMenuView,leftAlpha);
        // 缩放 0.7f - 1.0f
        float leftScale = 0.7f + (1-scale)*0.3f;
        ViewCompat.setScaleX(mMenuView,leftScale);
        ViewCompat.setScaleY(mMenuView, leftScale);
        // 最后一个效果 退出这个按钮刚开始是在右边，安装我们目前的方式永远都是在左边
        // 设置平移，先看一个抽屉效果
//         ViewCompat.setTranslationX(mMenuView,l);
        // 平移 l*0.7f
        ViewCompat.setTranslationX(mMenuView, 0.25f*l);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mIsIntercept = false;
        // 打开菜单，且手指点击右边区域，需要拦截事件 true。
        // 当菜单打开的时候，手指触摸右边内容区域要关闭菜单；还需要拦截事件(不响应进个人详情页等逻辑)
        if (mMenuIsOpen ) {
           float currentX =  ev.getX(); // 获取点击的x坐标。
           if (currentX > mMenuWidth) {
               closeMenu(); // 关闭菜单
               mIsIntercept = true; // 需要拦截
               return true; // 子view不响应事件（拦截子view的事件，但是还会响应自己的onTouchEvent）
           }
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mIsIntercept) return true; // 有拦截，就不执行自己的onTouch事件。
        if (mGestureDetector.onTouchEvent(ev)) {
            return true; // 不往下执行
        }
        // TODO: 菜单打开时，手指触摸内容区域，需要关闭菜单。还需要拦截事件。
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            // 只要管手指抬起。根据当前滚动距离来判断。关闭还是打开菜单。
            int currentScrollX = getScrollX();
            if (currentScrollX > mMenuWidth / 2) { // 关闭
                closeMenu();
            } else { // 打开
                openMenu();
            }
            return true; // 确保super的onTouchEvent不会执行。
        }
        return super.onTouchEvent(ev);
    }


    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
